//
// Created by Soar Qin on 2017/8/31.
// Copyright (c) 2017 Soar Qin. All rights reserved.
//

#include "common.hh"

#include "kcp_endpoint.hh"

#include "kcp_client.hh"
#include "ip_addr.hh"

#include <unordered_map>

namespace core::async {

struct KCPEndpointContext {
    std::unordered_map<IPAddr, KCPClient*, IPAddrHash> conn;
};

KCPEndpoint::KCPEndpoint(Loop &loop) : UDPEndpoint(loop), kcp_(new KCPEndpointContext) {
}

KCPEndpoint::~KCPEndpoint() {
    for (auto &p: kcp_->conn)
        delete p.second;
    kcp_->conn.clear();
    delete kcp_;
}

bool KCPEndpoint::assign(uint32_t conv, const IPAddr &to) {
    auto *&kcpclient = kcp_->conn[to];
    if (kcpclient != nullptr) return false;
    kcpclient = new KCPClient(this);
    if (kcpclient->init(conv, to)) return true;
    delete kcpclient;
    kcp_->conn.erase(to);
    return false;
}

void KCPEndpoint::onRead(const void *buf, size_t size, const IPAddr &from) {
    auto ite = kcp_->conn.find(from);
    if (ite == kcp_->conn.end()) return;
    ite->second->input(buf, size);
}

}
